#pragma once

#include "para.h"
#include "atom.h"
//#include "autocorr_CUDA.cuh"
#include <fstream>


class mol_sys{
public:
	mol_sys();

	int Natoms;
	double temperature;
	double potential_energy;
	double kenetic_energy;
	double total_energy;

	std::vector<Atom>mol;

	/**************************************************************************Classic**************************************************************************/
	static double Compute_sys_Ek(const std::vector<Atom> mol);
	static double Compute_sys_Ep(const std::vector<Atom>mol);
	static double Compute_Temperature(const std::vector<Atom>& mol, const double Ek);
	static void Compute_Temperature_and_Pressure(const std::vector<Atom>& mol, double& Ek, double& temperature, double& configurational_pressure);
	static double compute_velocities_average(std::vector<Atom> mol);
	static double compute_forces_average(std::vector<Atom> mol);
	static std::vector<double> compute_coord_average(std::vector<Atom> mol);
	static double autocorr(const int Tau, const int seq);
	static double autocorr_4_sys(const int tau);
	static std::vector<double> autocorr_store();
	static double Diffusion_Coefficient(std::vector<double> acf);




	/**************************************************************************PIMD**************************************************************************/

	/*************************energy calculating*************************/
	static double Compute_E_spr(std::vector< std::vector<Atom> > &mirr);
	static double Compute_Ek_vir(std::vector< std::vector<Atom> > &mirr);
	static double Compute_Ek_vircen(std::vector< std::vector<Atom> >&mirr);
	static double Compute_Ek_prim(std::vector< std::vector<Atom> > &mirr);
	static double Compute_Ek_stage(std::vector< std::vector<Atom> > &mirr);
	static double Compute_E_spr_stage(std::vector< std::vector<Atom> > &mirr);
	static double Compute_Ep_stage(std::vector< std::vector<Atom> >& mirr);
	//static void Compute_Temperature_and_Pressure(const std::vector<Atom>& mol, double& Ek, double& temperature, double& configurational_pressure);


	static double hamiltonian_compute_staging();



	/*************************staging transform*************************/
	static void mass_staging_transform(std::vector<Atom> mol, std::vector< std::vector<Atom> >& stag_mirr);
	static void coord_staging_transform();
	static void coord_inverse();
	static void forces_staging_transform();
	static void velocities_update_PIMD_staging();
	static void staging_transform();




	static double max_veloc();
	static double max_coord(std::vector<std::vector<Atom>>mirr);
	static double max_force(std::vector<std::vector<Atom>>mirr);


};



